home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / system / bbs / pub_acc.taz / pub_acc / banner.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-12-23  |  8.2 KB  |  662 lines

  1. /* 
  2.  * Prints the text given on the command line as a 4 line banner.  If no text
  3.  * is given on the command line, it runs as a filter instead, reading input
  4.  * from stdin and printing the banner to stdout.  Lines exceeding 80 columns
  5.  * will be automatically wrapped, breaking arbitrarily between characters.
  6.  * Some kerning is done, and there is a weak attempt to put extra space between
  7.  * characters that might run together if printed too close together.
  8.  */
  9.  
  10. #include <stdio.h>
  11. #include <ctype.h>
  12.  
  13. #define SPACES    4    /* spaces to leave for a space */
  14. #define LINELEN    79    /* maximum output line length */
  15. #define CHEIGHT    4    /* height of characters not including decenders */
  16.             /* ...just changing CHEIGHT won't work */
  17.  
  18. struct{
  19.     char ch;
  20.     char *line[CHEIGHT+1];
  21.     } font[]= {
  22.  
  23.        {'A',
  24.        {"  __",
  25.     " /  \\",
  26.     "| () |",
  27.     "|_||_|",
  28.     ""}},
  29.  
  30.        {'B',
  31.        {" ____",
  32.     "| __ \\",
  33.     "| __ (",
  34.     "|____/",
  35.     ""}},
  36.  
  37.        {'C',
  38.        {"  ____",
  39.     " /  __)",
  40.     "(  (__",
  41.     " \\____)",
  42.     ""}},
  43.  
  44.        {'D',
  45.        {" ____",
  46.     "|  _ \\",
  47.     "| |_) )",
  48.     "|____/",
  49.     ""}},
  50.  
  51.        {'E',
  52.        {" ____",
  53.     "| ___)",
  54.     "| _)_",
  55.     "|____)",
  56.     ""}},
  57.  
  58.        {'F',
  59.        {" ____",
  60.     "| ___)",
  61.     "| __)",
  62.     "|_|",
  63.     ""}},
  64.  
  65.        {'G',
  66.        {"  ____",
  67.     " /  __)",
  68.     "(  (_  )",
  69.     " \\____/",
  70.     ""}},
  71.  
  72.        {'H',
  73.        {" _   _",
  74.     "| |_| |",
  75.     "|  _  |",
  76.     "|_| |_|",
  77.     ""}},
  78.  
  79.        {'I',
  80.        {" ___",
  81.     "(   )",
  82.     " | |",
  83.     "(___)",
  84.     ""}},
  85.  
  86.        {'J',
  87.        {"    _",
  88.     " _ | |",
  89.     "( )| |",
  90.     " \\__/",
  91.     ""}},
  92.  
  93.        {'K',
  94.        {" _  __",
  95.     "| |/ /",
  96.     "|   (",
  97.     "|_|\\_\\",
  98.     ""}},
  99.  
  100.        {'L',
  101.        {" _",
  102.     "| |",
  103.     "| |__",
  104.     "|____)",
  105.     ""}},
  106.  
  107.        {'M',
  108.        {" _    _",
  109.     "| \\  / |",
  110.     "| \\\\// |",
  111.     "|_|\\/|_|",
  112.     ""}},
  113.  
  114.        {'N',
  115.        {" _  _",
  116.     "| \\| |",
  117.     "| \\\\ |",
  118.     "|_|\\_|",
  119.     ""}},
  120.  
  121.        {'O',
  122.        {"  ___",
  123.     " / _ \\",
  124.     "( (_) )",
  125.     " \\___/",
  126.     ""}},
  127.  
  128.        {'P',
  129.        {" ____",
  130.     "| __ \\",
  131.     "|  __/",
  132.     "|_|",
  133.     ""}},
  134.  
  135.        {'Q',
  136.        {"  ___",
  137.     " / _ \\",
  138.     "( (_) )",
  139.     " \\__\\\\",
  140.     ""}},
  141.  
  142.        {'R',
  143.        {" ____",
  144.     "| __ \\",
  145.     "|    /",
  146.     "|_|\\_\\",
  147.     ""}},
  148.  
  149.        {'S',
  150.        {" ____",
  151.     "/ ___)",
  152.     "\\___ \\",
  153.     "(____/",
  154.     ""}},
  155.  
  156.        {'T',
  157.        {" _____",
  158.     "(_   _)",
  159.     "  | |",
  160.     "  |_|",
  161.     ""}},
  162.  
  163.        {'U',
  164.        {" _  _",
  165.     "| || |",
  166.     "| || |",
  167.     " \\__/",
  168.     ""}},
  169.  
  170.        {'V',
  171.        {"__  __",
  172.     "\\ \\/ /",
  173.     " \\  /",
  174.     "  \\/",
  175.     ""}},
  176.  
  177.        {'W',
  178.        {" _      _",
  179.     "( )    ( )",
  180.     " \\ \\()/ /",
  181.     "  \\_/\\_/",
  182.     ""}},
  183.  
  184.        {'X',
  185.        {"__  __",
  186.     "\\ \\/ /",
  187.     " )  (",
  188.     "/_/\\_\\",
  189.     ""}},
  190.  
  191.        {'Y',
  192.        {"__  __",
  193.     "\\ \\/ /",
  194.     " \\  /",
  195.     " /_/",
  196.     ""}},
  197.  
  198.        {'Z',
  199.        {" _____",
  200.     "(__  /",
  201.     "  / /_",
  202.     " /____)",
  203.     ""}},
  204.  
  205.        {'0',
  206.        {"  ___",
  207.     " /   \\",
  208.     "(  |  )",
  209.     " \\___/",
  210.     ""}},
  211.  
  212.        {'1',
  213.        {" __",
  214.     "/  |",
  215.     " | |",
  216.     "(___)",
  217.     ""}},
  218.  
  219.        {'2',
  220.        {" ____",
  221.     "(___ \\",
  222.     " / __/",
  223.     "/____)",
  224.     ""}},
  225.  
  226.        {'3',
  227.        {" ____",
  228.     "(___ \\",
  229.     " _(_ (",
  230.     "(____/",
  231.     ""}},
  232.  
  233.        {'4',
  234.        {"  ___",
  235.     " / _ |",
  236.     "/__   )",
  237.     "   |_|",
  238.     ""}},
  239.  
  240.        {'5',
  241.        {" ____",
  242.     "| ___)",
  243.     "|___ \\",
  244.     "(____/",
  245.     ""}},
  246.  
  247.        {'6',
  248.        {"  ___",
  249.     " / __)",
  250.     "(  _ \\",
  251.     " \\___/",
  252.     ""}},
  253.  
  254.        {'7',
  255.        {" _____",
  256.     "(__  / ",
  257.     "  / /",
  258.     " /_/",
  259.     ""}},
  260.  
  261.        {'8',
  262.        {" ___",
  263.     "/ _ \\",
  264.     ") _ (",
  265.     "\\___/",
  266.     ""}},
  267.  
  268.        {'9',
  269.        {" ___",
  270.     "/ _ \\",
  271.     "\\__  )",
  272.     "(___/",
  273.     ""}},
  274.  
  275.        {'\047',
  276.        {" _",
  277.     "(_)",
  278.     " /",
  279.     "",
  280.     ""}},
  281.  
  282.        {';',
  283.        {"",
  284.     " _",
  285.     "(_)",
  286.     "(_)",
  287.     " /"}},
  288.  
  289.        {',',
  290.        {"",
  291.     "",
  292.     " _",
  293.     "(_)",
  294.     " /"}},
  295.  
  296.        {'`',
  297.        {" _",
  298.     "(_)",
  299.     " \\",
  300.     "",
  301.     ""}},
  302.  
  303.        {'"',
  304.        {" _ _",
  305.     "(_(_)",
  306.     " / /",
  307.     "",
  308.     ""}},
  309.  
  310.        {'-',
  311.        {"",
  312.     " ___",
  313.     "(___)",
  314.     "",
  315.     ""}},
  316.  
  317.        {'_',
  318.        {"",
  319.     "",
  320.     " ___",
  321.     "(___)",
  322.     ""}},
  323.  
  324.        {'.',
  325.        {"",
  326.     "",
  327.     " _",
  328.     "(_)",
  329.     ""}},
  330.  
  331.        {'/',
  332.        {"   __",
  333.     "  / /",
  334.     " / /",
  335.     "/_/",
  336.     ""}},
  337.  
  338.        {'\\',
  339.        {"__",
  340.     "\\ \\",
  341.     " \\ \\",
  342.     "  \\_\\",
  343.     ""}},
  344.  
  345.        {'|',
  346.        {" _",
  347.     "| |",
  348.     "| |",
  349.     "|_|",
  350.     ""}},
  351.  
  352.        {':',
  353.        {"",
  354.     " _",
  355.     "(_)",
  356.     "(_)",
  357.     ""}},
  358.  
  359.        {'(',
  360.        {"  __",
  361.     " / /",
  362.     "( (",
  363.     " \\_\\",
  364.     ""}},
  365.  
  366.        {')',
  367.        {"__  ",
  368.     "\\ \\",
  369.     " ) )",
  370.     "/_/",
  371.     ""}},
  372.  
  373.        {'!',
  374.        {" _",
  375.     "| |",
  376.     "|_|",
  377.     "(_)",
  378.     ""}},
  379.  
  380.        {'?',
  381.        {" ___",
  382.     "(__ \\",
  383.     " |__/",
  384.     " (_)",
  385.     ""}},
  386.  
  387.        {'%',
  388.        {" _  __",
  389.     "(_)/ /",
  390.     "  / /_",
  391.     " /_/(_)",
  392.     ""}},
  393.  
  394.        {'&',
  395.        {"  _",
  396.     " ( )",
  397.     "/  \\_",
  398.     "\\___(",
  399.     ""}},
  400.  
  401.        {'^',
  402.        {"",
  403.     " /\\",
  404.     "//\\\\",
  405.     "",
  406.     ""}},
  407.  
  408.        {'=',
  409.        {"",
  410.     " ___",
  411.     "(___)",
  412.     "(___)",
  413.     ""}},
  414.  
  415.        {'+',
  416.        {"   _",
  417.     " _| |_",
  418.     "(_   _)",
  419.     "  |_|",
  420.     ""}},
  421.  
  422.        {'[',
  423.        {" _",
  424.     "| )",
  425.     "||",
  426.     "|_)",
  427.     ""}},
  428.  
  429.        {']',
  430.        {" _",
  431.     "( |",
  432.     " ||",
  433.     "(_|",
  434.     ""}},
  435.  
  436.        {'{',
  437.        {"  _",
  438.     " | /",
  439.     "< (",
  440.     " |_\\",
  441.     ""}},
  442.  
  443.        {'}',
  444.        {" _",
  445.     "\\ |",
  446.     " ) >",
  447.     "/_|",
  448.     ""}},
  449.  
  450.        {'$',
  451.        {" _.._",
  452.     "/ ||_)",
  453.     "\\_|| \\",
  454.     "(_||_/",
  455.     ""}},
  456.  
  457.        {'*',
  458.        {" __  __",
  459.     " \\ \\/ /",
  460.     "(_    _)",
  461.     " /_/\\_\\",
  462.     ""}},
  463.  
  464.        {'@',
  465.        {"  ___",
  466.     " / __\\",
  467.     "( (o(_)",
  468.     " \\___/",
  469.     ""}},
  470.  
  471.        {'~',
  472.        {"",
  473.     "  _",
  474.     " /_\\_/)",
  475.     "(/ \\_/",
  476.     ""}}, 
  477.  
  478.        {'>',
  479.        {"__",
  480.     "\\ \\",
  481.     " > >",
  482.     "/_/",
  483.     ""}},
  484.  
  485.        {'<',
  486.        {"  __",
  487.     " / /",
  488.     "< <",
  489.     " \\_\\",
  490.     ""}},
  491.  
  492.        /* This marks the end of the character table */
  493.  
  494.        {'\0',
  495.        {NULL,
  496.     NULL,
  497.     NULL,
  498.     NULL,
  499.     NULL}}
  500.     };
  501.  
  502. main(argc,argv)
  503. int argc;
  504. char **argv;
  505. {
  506. char dave[256];
  507. int i;
  508.  
  509.     if (argc == 1)
  510.     {
  511.         while(fgets(dave,255,stdin) != NULL)
  512.             kite(dave);
  513.     }
  514.     else
  515.     {
  516.         dave[0]= '\0';
  517.         for (i=1; i < argc; i++)
  518.         {
  519.             strcat(dave,argv[i]);
  520.             if (i != argc-1)
  521.                 strcat(dave," ");
  522.         }
  523.         kite(dave);
  524.     }
  525. }
  526.  
  527. char buf[CHEIGHT+1][LINELEN+1]; /* output buffer */
  528. int i[CHEIGHT+1];        /* indexes into the output buffer lines */
  529. int printlast;            /* should we print descender line? */
  530.  
  531. kite(s)
  532. char *s;
  533. {
  534. int j,k,n;
  535. char chr,chl;
  536. int pad;
  537. int l[CHEIGHT+1];
  538. int f[CHEIGHT+1],minstart;
  539.  
  540.     i[0]= i[1]= i[2]= i[3]= i[4]= 0;
  541.     printlast= 0;
  542.  
  543.     for (;*s != '\0'; s++)
  544.     {
  545.         /* Process spaces */
  546.         if (*s == ' ' || *s == '\t')
  547.         {
  548.             if (makeroom(SPACES,SPACES,SPACES,SPACES,SPACES))
  549.             {
  550.                 for(j=0; j<SPACES; j++)
  551.                 {
  552.                     buf[0][i[0]++]= ' ';
  553.                     buf[1][i[1]++]= ' ';
  554.                     buf[2][i[2]++]= ' ';
  555.                     buf[3][i[3]++]= ' ';
  556.                     buf[4][i[4]++]= ' ';
  557.                 }
  558.             }
  559.         }
  560.  
  561.         /* Convert to upper case */
  562.         if (islower(*s)) *s= toupper(*s);
  563.  
  564.         /* Find the character in the font table */
  565.         for (n=0; (font[n].ch != '\0') && (font[n].ch != *s); n++)
  566.             ;
  567.         if (font[n].ch == '\0')
  568.             continue;
  569.         
  570.         /* Find leftmost non-overlapping position for next char */
  571.         minstart= 0;
  572.         for (j= 0; j < CHEIGHT+1; j++)
  573.         {
  574.             l[j]= strlen(font[n].line[j]);
  575.  
  576.             f[j]= first(font[n].line[j]);
  577.             if (f[j] != -1 && i[j]-f[j] > minstart)
  578.                 minstart= i[j]-f[j];
  579.         }
  580.  
  581.         /* See if we need an extra space to keep the letters apart */
  582.         pad= 0;
  583.         for (j= 0; j < CHEIGHT+1; j++)
  584.         {
  585.             if (f[j] != -1)
  586.             {
  587.                 if (minstart+f[j] > i[j] ||
  588.                     minstart+f[j] <= 0) continue;
  589.                 chl= buf[j][minstart+f[j]-1];
  590.                 chr= font[n].line[j][f[j]];
  591.                 if (chl != ' ' && chl != ')' &&
  592.                     chr != ' ' && chr != '(') pad= 1;
  593.             }
  594.         }
  595.         minstart += pad;
  596.  
  597.         /* Make sure we have room for the letter */
  598.         if (!makeroom(minstart-i[0]+l[0],
  599.                       minstart-i[1]+l[1],
  600.                       minstart-i[2]+l[2],
  601.                       minstart-i[3]+l[3],
  602.                       minstart-i[4]+l[4]))
  603.             minstart=0;
  604.         
  605.         /* Store the letter */
  606.         for (j= 0; j < CHEIGHT+1; j++)
  607.         {
  608.             for (k= i[j]; k < minstart; k++)
  609.                 buf[j][k]= ' ';
  610.  
  611.             for (k= 0; k < l[j]; k++)
  612.             {
  613.                 if (font[n].line[j][k] != ' ' ||
  614.                     minstart+k >= i[j])
  615.                 {
  616.                     buf[j][minstart+k]= font[n].line[j][k];
  617.                     if (j==4 && font[n].line[j][k] != ' ')
  618.                         printlast= 1;
  619.                 }
  620.             }
  621.             if (minstart+l[j] > i[j])
  622.                 i[j]= minstart+l[j];
  623.         }
  624.     }
  625.     printbuf();
  626. }
  627.  
  628. int first(s)
  629. char *s;
  630. {
  631. int i;
  632.     for (i= 0; s[i] != '\0'; i++)
  633.         if (s[i] != ' ') return(i);
  634.     return(-1);
  635. }
  636.  
  637. makeroom(s0,s1,s2,s3,s4)
  638. int s0,s1,s2,s3,s4;
  639. {
  640.     if ( i[0]+s0 > LINELEN-1 || i[1]+s1 > LINELEN-1 ||
  641.          i[2]+s2 > LINELEN-1 || i[3]+s3 > LINELEN-1 || i[4]+s4 > LINELEN-1)
  642.     {
  643.         printbuf();
  644.         return(0);
  645.     }
  646.     return(1);
  647. }
  648.  
  649. printbuf()
  650. {
  651. int j;
  652.     for (j= 0; j < CHEIGHT+printlast; j++)
  653.     {
  654.         buf[j][i[j]]= '\0';
  655.         puts(buf[j]);
  656.         i[j]= 0;
  657.     }
  658.     printlast= 0;
  659. }
  660.  
  661.  
  662.